package com.jinmdz.fmis.api.api.service;

import com.jinmdz.fmis.api.api.model.cremation.certificate.*;
import com.jinmdz.fmis.api.api.model.funeral.BusinessCodeData;
import com.jinmdz.fmis.api.api.model.funeral.negotiation.NegotiationAgentItem;
import com.jinmdz.fmis.api.api.model.funeral.negotiation.NegotiationDeadItem;
import com.jinmdz.fmis.api.api.model.funeral.negotiation.NegotiationMemberItem;
import com.jinmdz.fmis.api.base.BaseService;
import com.jinmdz.fmis.api.constant.MessageConst;
import com.jinmdz.fmis.api.model.config.dictionary.BusinessLogCode;
import com.jinmdz.fmis.api.model.config.dictionary.DictionaryCode;
import com.jinmdz.fmis.api.model.config.dictionary.OperationLogCode;
import com.jinmdz.fmis.api.model.system.UserItem;
import com.jinmdz.fmis.api.wrapper.DictionaryWrapper;
import com.jinmdz.fmis.api.wrapper.OperationWrapper;
import com.jinmdz.fmis.common.ext.StringBuilderExt;
import com.jinmdz.fmis.common.util.BeanUtil;
import com.jinmdz.fmis.common.util.DataUtil;
import com.jinmdz.fmis.core.base.BaseResult;
import com.jinmdz.fmis.core.exception.ActionException;
import com.jinmdz.fmis.core.util.JacksonUtil;
import com.jinmdz.fmis.dao.dao.*;
import com.jinmdz.fmis.dao.model.cremation.CremationCertificatePrintingHistoryItem;
import com.jinmdz.fmis.dao.model.cremation.CremationViewItem;
import com.jinmdz.fmis.dao.model.funeral.FamilyAgentItem;
import com.jinmdz.fmis.dao.model.funeral.FamilyMemberItem;
import com.jinmdz.fmis.dao.model.funeral.FuneralBusinessViewItem;
import com.jinmdz.fmis.dao.model.funeral.FuneralDeadItem;
import com.jinmdz.fmis.mapper.entity.CremationCertificatePrintingHistoryEntity;
import com.jinmdz.fmis.mapper.entity.FuneralBusinessLogEntity;
import com.jinmdz.fmis.mapper.mapper.CremationCertificatePrintingHistoryMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;


/**
 * 火化证打印Service
 *
 * @author GuanKui
 * @date 2020/2/19 11:35
 */
@Service("cremationCertificatePrintingService")
public class CremationCertificatePrintingService extends BaseService {

    @Resource
    private FuneralBusinessDao funeralBusinessDao;

    @Resource
    private FuneralDeadDao funeralDeadDao;

    @Resource
    private FamilyMemberDao familyMemberDao;

    @Resource
    private FamilyAgentDao familyAgentDao;

    @Resource
    private DictionaryService dictionaryService;

    @Resource
    private DictionaryWrapper dictionaryWrapper;

    @Resource
    private CremationCertificatePrintingHistoryDao cremationCertificatePrintingHistoryDao;

    @Resource
    private CremationDao cremationDao;

    @Resource
    private CremationCertificatePrintingHistoryMapper cremationCertificatePrintingHistoryMapper;

    @Resource
    private DictionaryCode dictionaryCode;

    @Resource
    private BusinessLogCode businessLogCode;

    @Resource
    private OperationWrapper operationWrapper;

    @Resource
    private OperationLogCode operationLogCode;

    /**
     * 根据funeral_dead表中businessCode加载逝者火化证件打印
     *
     * @param data 业务编码
     * @return
     * @author GuanKui
     * @date 2020/2/21 9:37
     */
    public BaseResult<CremationCertificatePrintingItem> loadCremationCertificatePrintingAll(CremationCertificatePrintingAllData data) {

        String businessCode = data.getBusinessCode();
        // 通过业务编码获取殡葬信息
        FuneralBusinessViewItem funeralItem = funeralBusinessDao.getFuneralBusinessViewByBusinessCode(businessCode);
        if (DataUtil.isNull(funeralItem) || DataUtil.isNull(funeralItem.getId(), funeralItem.getVersion())) {
            return failure(MessageConst.BUSINESS_CODE_ERROR);
        }

        // 获取激活状态的火化任务
        CremationViewItem cremationViewItem = cremationDao.getCremationViewAsActiveByBusinessCode(businessCode);
        if (cremationViewItem == null) {
            return failure("火化信息不存在");
        }

        CremationCertificatePrintingItem loadItem = new CremationCertificatePrintingItem();

        // 获取逝者信息
        FuneralDeadItem funeralDeadItem = funeralDeadDao.getFuneralDeadByBusinessCode(businessCode);
        if (funeralDeadItem != null) {
            NegotiationDeadItem deadItem = BeanUtil.copy2Bean(funeralDeadItem, new NegotiationDeadItem());
            // 设置字典文本
            dictionaryWrapper.resetDataText(deadItem);
            loadItem.setFuneralDead(deadItem);
        }

        // 获取家属信息
        FamilyMemberItem familyMemberItem = familyMemberDao.getFamilyMemberByBusinessCode(businessCode);
        if (familyMemberItem != null) {
            NegotiationMemberItem memberItem = BeanUtil.copy2Bean(familyMemberItem, new NegotiationMemberItem());
            dictionaryWrapper.resetDataText(memberItem);
            loadItem.setFamilyMember(memberItem);
        }

        // 获取承办人信息
        FamilyAgentItem familyAgentItem = familyAgentDao.getFamilyAgentByBusinessCode(businessCode);
        if (familyAgentItem != null) {
            NegotiationAgentItem agentItem = BeanUtil.copy2Bean(familyAgentItem, new NegotiationAgentItem());
            dictionaryWrapper.resetDataText(agentItem);
            loadItem.setFamilyAgent(agentItem);
        }

        // 加载火化数据
        loadItem.setCremation(BeanUtil.copy2Bean(cremationViewItem, new CremationCertificatePrintingCremationItem()));
        // 加载字典数据
        loadItem.setDicts(dictionaryService.loadDictionaryMap(data.getDictTypeCodes()));

        // 获取打印记录
        ArrayList<CremationCertificatePrintingHistoryItem> historyViewItems = cremationCertificatePrintingHistoryDao.listCremationCertificatePrintingHistoryByBusinessCode(businessCode);
        dictionaryWrapper.resetDataText(historyViewItems);
        // 加载打印记录
        loadItem.setPrintHistory(historyViewItems);

        return successData(loadItem);
    }

    /**
     * 保存火化证打印信息
     *
     * @param userItem 当前帐号
     * @param data     打印保存数据
     * @return
     * @author GuanKui
     * @date 2020/2/19  16:39
     */
    @Transactional(rollbackFor = Exception.class)
    public BaseResult<CremationCertificatePrintingItem> saveCremationCertificatePrinting(UserItem userItem, CremationCertificatePrintingSaveData data) throws ActionException {
        String businessCode = data.getBusinessCode();
        // 通过业务编码获取殡葬信息
        FuneralBusinessViewItem funeralItem = funeralBusinessDao.getFuneralBusinessViewByBusinessCode(businessCode);
        if (DataUtil.isNull(funeralItem) || DataUtil.isNull(funeralItem.getId(), funeralItem.getVersion())) {
            throw exception(MessageConst.BUSINESS_CODE_ERROR);
        }

        // 获取火化火化任务信息
        CremationViewItem cremationViewItem = cremationDao.getCremationViewById(data.getCremationId());
        if (cremationViewItem == null) {
            throw exception("火化信息不存在");
        }

        // 验证火化任务版本号
        if (cremationViewItem.getVersion().intValue() != data.getCremationVersion().intValue()) {
            throw exception(versionError("火化信息"));
        }

        // 验证火化任务激活状态
        if (DataUtil.invalid(cremationViewItem.getAsActive())) {
            throw exception("火化信息未激活");
        }

        // 验证业务编码
        if (!businessCode.equals(cremationViewItem.getBusinessCode())) {
            throw exception(MessageConst.BUSINESS_CODE_ERROR);
        }

        // 获取家属信息
        FamilyMemberItem familyMemberItem = familyMemberDao.getFamilyMemberByBusinessCode(businessCode);
        if (familyMemberItem == null) {
            throw exception("逝者家属信息不存在");
        }
        // 验证逝者家属信息版本
        if (data.getMemberVersion().intValue() != familyMemberItem.getVersion().intValue()) {
            throw exception(versionError("逝者家属信息"));
        }

        // 验证业务编码
        if (!businessCode.equals(familyMemberItem.getBusinessCode())) {
            throw exception(MessageConst.BUSINESS_CODE_ERROR);
        }

        // 当发证时，判断是否存在火化证
        if (DataUtil.inIntegers(data.getOperationTypeCode(), dictionaryCode.getCremationPrintingTypeFaZheng())) {
            // 判断火化证号是否存在
            String cremationNo = cremationDao.hasCremationNo(data.getCremationNewNo());
            if (DataUtil.valid(cremationNo)) {
                throw exception("火化证号已存在");
            }
        }

        // 当重打，判断是证件号是否相同
        if (DataUtil.inIntegers(data.getOperationTypeCode(), dictionaryCode.getCremationPrintingTypeChongDa())) {
            if (!data.getCremationNewNo().equals(cremationViewItem.getCremationNo())) {
                throw exception("重打的火化证号不正确，请核实后再重打");
            }

            // 重打时，操作原因必填
            if (DataUtil.invalid(data.getOperationCause())) {
                throw exception("重打时必填操作原因");
            }
        }

        // 无论发证还是重打，都将原有证书号覆盖
        data.setCremationOldNo(cremationViewItem.getCremationNo());

        // 创建单表提交实体
        CremationCertificatePrintingHistoryEntity entity = getEntity(userItem, CremationCertificatePrintingHistoryEntity.class);
        // 覆盖数据
        BeanUtil.copy2Bean(data, entity);
        // 将家属信息赋值给记录表
        entity.setAddress(familyMemberItem.getAddress())
                .setCertificateNo(familyMemberItem.getCertificateNo())
                .setCertificateTypeCode(familyMemberItem.getCertificateTypeCode())
                .setMemberGenderCode(familyMemberItem.getMemberGenderCode())
                .setMemberId(familyMemberItem.getId())
                .setMobilePhone(familyMemberItem.getMobilePhone())
                .setMemberRelation(familyMemberItem.getMemberRelation())
                .setMemberName(familyMemberItem.getMemberName())
                .setOtherPhone(familyMemberItem.getOtherPhone())
                .setOperationTime(new Date());

        // 插入打印记录
        cremationCertificatePrintingHistoryMapper.insertCremationCertificatePrintingHistory(entity);
        // 判断保存信息结果
        if (DataUtil.invalid(entity.getId())) {
            throw exception("保存打印记录失败");
        }

        // 根据火化表ID修改火化证号
        cremationDao.updateCremationCertificateNoById(cremationViewItem.getId(), data.getCremationNewNo(), userItem.getId(), cremationViewItem.getVersion());

        // 添加日志信息
        saveCremationCertificatePrintLog(userItem, funeralItem, data, entity);

        // 生成新的查询请求体
        CremationCertificatePrintingAllData printData = new CremationCertificatePrintingAllData();
        printData.setBusinessCode(data.getBusinessCode());

        return loadCremationCertificatePrintingAll(printData);
    }

    /**
     * 添加火化证日志记录
     *
     * @param userItem    当前帐号
     * @param funeralItem 当前业务
     * @param data        请求数据
     * @param entity      实体信息
     * @return
     * @author LiCongLu
     * @date 2020-02-26 09:36
     */
    private void saveCremationCertificatePrintLog(UserItem userItem, FuneralBusinessViewItem funeralItem, CremationCertificatePrintingSaveData data, CremationCertificatePrintingHistoryEntity entity) throws ActionException {

        // 添加业务日志及操作日志
        String businessCode = funeralItem.getBusinessCode();
        boolean cremationType = DataUtil.inIntegers(data.getOperationTypeCode(), dictionaryCode.getCremationPrintingTypeFaZheng());
        Integer typeCode = cremationType ? businessLogCode.getCremationFaZheng() : businessLogCode.getCremationChongDa();
        FuneralBusinessLogEntity businessLogEntity = operationWrapper.businessLog(userItem, businessCode, typeCode);

        // 操作日志字符串
        StringBuilderExt builder = new StringBuilderExt();
        builder.format("火化证号，业务编码[{0}]，逝者姓名[{1}]，旧火化证号[{2}]，新火化证号[{3}]，操作人员[{4}]"
                , businessCode, funeralItem.getDeadName()
                , entity.getCremationOldNo(), entity.getCremationNewNo()
                , userItem.getFullName());

        Integer logTypeCode = cremationType ? operationLogCode.getCremationFaZheng() : operationLogCode.getCremationChongDa();
        // 添加日志
        operationWrapper.operationLog(userItem, businessLogEntity, logTypeCode
                , builder.toString(), JacksonUtil.obj2Json(data), null, JacksonUtil.obj2Json(entity));
    }

    /**
     * 根据funeral_dead表中businessCode加载打印火化证/火化证明信息
     *
     * @param userItem 当前账号
     * @param data     业务编码
     * @return
     * @author LiCongLu
     * @date 2020-04-10 15:30
     */
    public BaseResult<CremationCertificateItem> loadPrintCremationCertificateWithBusinessCode(UserItem userItem, BusinessCodeData data) {
        String businessCode = data.getBusinessCode();
        // 通过业务编码获取殡葬信息
        FuneralBusinessViewItem funeralItem = funeralBusinessDao.getFuneralBusinessViewByBusinessCode(businessCode);
        if (DataUtil.isNull(funeralItem) || DataUtil.isNull(funeralItem.getId(), funeralItem.getVersion())) {
            return failure(MessageConst.NO_FUNERAL_CODE);
        }

        // 获取激活状态的火化任务
        CremationViewItem cremationViewItem = cremationDao.getCremationViewAsActiveByBusinessCode(businessCode);
        if (cremationViewItem == null) {
            return failure("火化信息不存在");
        }

        // 创建响应实体
        CremationCertificateItem loadItem = new CremationCertificateItem();

        // 殡葬信息
        loadItem.setBusinessCode(businessCode)
                .setPrintDate(nowDate());

        // 获取逝者信息
        FuneralDeadItem funeralDeadItem = funeralDeadDao.getFuneralDeadByBusinessCode(businessCode);
        BeanUtil.copy2Bean(funeralDeadItem, loadItem);

        // 获取家属信息
        loadItem.setMemberName(funeralItem.getMemberName());

        // 初始化字典文本
        dictionaryWrapper.resetDataText(loadItem);

        // 设置火化信息
        loadItem.setAppointmentDate(cremationViewItem.getAppointmentDate())
                .setCremationNo(cremationViewItem.getCremationNo());
        // 当前账号信息
        loadItem.setUserFullName(userItem.getFullName());

        return successData(loadItem);
    }
}
